001 /* 002 * Copyright 2005 Niclas Hedhman 003 * Copyright 2005 Stephen J. McConnell. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 014 * implied. 015 * 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 package net.dpml.transit.link; 021 022 import java.io.IOException; 023 import java.io.InputStream; 024 import java.io.OutputStream; 025 import java.net.URI; 026 import java.net.URL; 027 import java.net.URLConnection; 028 import java.security.AccessController; 029 import java.security.PrivilegedExceptionAction; 030 import java.security.PrivilegedActionException; 031 import java.security.PrivilegedAction; 032 033 import net.dpml.transit.Transit; 034 import net.dpml.transit.Artifact; 035 import net.dpml.transit.UnsupportedSchemeException; 036 import net.dpml.util.MimeTypeHandler; 037 038 /** 039 * link: URL protocol connection processor. 040 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 041 * @version 1.0.2 042 */ 043 public class LinkURLConnection extends URLConnection 044 { 045 private boolean m_connected; 046 private URL m_targetURL; 047 048 /** 049 * Creation of a new handler. 050 * @param url the url to establish a connection with 051 * @exception NullPointerException if the url argument is null 052 */ 053 LinkURLConnection( URL url ) 054 throws NullPointerException 055 { 056 super( url ); 057 m_connected = false; 058 } 059 060 /** 061 * Establish a connection. 062 * 063 * @exception IOException is an error occurs while attempting to establish 064 * the connection. 065 */ 066 public void connect() 067 throws IOException 068 { 069 if( m_connected ) 070 { 071 return; 072 } 073 074 m_connected = true; 075 076 try 077 { 078 AccessController.doPrivileged( 079 new PrivilegedExceptionAction() 080 { 081 public Object run() 082 throws IOException 083 { 084 URI linkUri = URI.create( url.toExternalForm() ); 085 LinkManager manager = Transit.getInstance().getLinkManager(); 086 URI targetUri = manager.getTargetURI( linkUri ); 087 if( targetUri != null ) 088 { 089 try 090 { 091 Artifact artifact = Artifact.createArtifact( targetUri ); 092 m_targetURL = artifact.toURL(); 093 } 094 catch( UnsupportedSchemeException use ) 095 { 096 m_targetURL = new URL( targetUri.toASCIIString() ); 097 } 098 } 099 else 100 { 101 m_targetURL = null; 102 } 103 return null; // nothing to return 104 } 105 } 106 ); 107 } 108 catch( PrivilegedActionException e ) 109 { 110 throw (IOException) e.getException(); 111 } 112 } 113 114 /** 115 * Return an input stream to the resource. 116 * @return the input stream 117 * @exception IOException is an error occurs 118 */ 119 public InputStream getInputStream() 120 throws IOException 121 { 122 connect(); 123 if( m_targetURL == null ) 124 { 125 return null; 126 } 127 else 128 { 129 URLConnection conn = m_targetURL.openConnection(); 130 InputStream in = conn.getInputStream(); 131 return in; 132 } 133 } 134 135 /** 136 * Return an output stream to the resource. 137 * @return the output stream 138 * @exception IOException if any I/O problems occur. 139 */ 140 public OutputStream getOutputStream() 141 throws IOException 142 { 143 connect(); 144 if( m_targetURL == null ) 145 { 146 return null; 147 } 148 else 149 { 150 URLConnection conn = m_targetURL.openConnection(); 151 OutputStream out = conn.getOutputStream(); 152 return out; 153 } 154 } 155 156 /** 157 * Reutrn the mimetype of the content. 158 * @return the content mimetype 159 */ 160 public String getContentType() 161 { 162 return MimeTypeHandler.getMimeType( "link" ); 163 } 164 165 /** 166 * Return the content for this Link. 167 * @param classes a sequence of classes against which the 168 * implementation will attempt to establish a known match 169 * @return the content object (possibly null) 170 * @exception IOException is an error occurs 171 */ 172 public Object getContent( final Class[] classes ) 173 throws IOException 174 { 175 final LinkManager manager = Transit.getInstance().getLinkManager(); 176 177 Object result = AccessController.doPrivileged( 178 new PrivilegedAction() 179 { 180 public Object run() 181 { 182 for( int i=0; i < classes.length; i++ ) 183 { 184 Class c = classes[i]; 185 if( c.equals( Link.class ) ) 186 { 187 String extUri = getURL().toString(); 188 URI uri = URI.create( extUri ); 189 Link link = new Link( uri, manager ); 190 return link; 191 } 192 if( c.equals( URI.class ) ) 193 { 194 String extUri = getURL().toString(); 195 URI uri = URI.create( extUri ); 196 return uri; 197 } 198 } 199 return null; 200 } 201 } 202 ); 203 204 if( null != result ) 205 { 206 return result; 207 } 208 else 209 { 210 connect(); 211 if( null != m_targetURL ) 212 { 213 return m_targetURL.getContent( classes ); 214 } 215 else 216 { 217 return super.getContent( classes ); 218 } 219 } 220 } 221 }